<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是STM32开发——STM32启动文件的一些的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV16-11-STM32启动-01-STM32的启动文件">
<meta property="og:url" content="https://sumumm.github.io/post/a7da6abe.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是STM32开发——STM32启动文件的一些的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530123816126.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530123929191.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530124708848.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530125316861.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230409215812433.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530125809011.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530130729695.png">
<meta property="article:published_time" content="2023-06-04T14:06:47.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.008Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV16-STM32开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530123816126.png">


<link rel="canonical" href="https://sumumm.github.io/post/a7da6abe.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/a7da6abe.html","path":"post/a7da6abe.html","title":"LV16-11-STM32启动-01-STM32的启动文件"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV16-11-STM32启动-01-STM32的启动文件 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6"><span class="nav-text">一、启动文件</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6%E7%AE%80%E4%BB%8B"><span class="nav-text">1. 启动文件简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6%E5%9C%A8%E5%93%AA%EF%BC%9F"><span class="nav-text">2. 启动文件在哪？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%9F%A5%E6%89%BEARM%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4%E8%B5%84%E6%96%99"><span class="nav-text">3. 查找ARM汇编指令资料</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6%E5%88%86%E6%9E%90"><span class="nav-text">二、启动文件分析</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-Stack%E2%80%94%E2%80%94%E6%A0%88"><span class="nav-text">1. Stack——栈</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-Heap%E2%80%94%E2%80%94%E5%A0%86"><span class="nav-text">2. Heap——堆</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%A0%86%E6%A0%88%E5%AF%B9%E9%BD%90"><span class="nav-text">3. 堆栈对齐</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%90%91%E9%87%8F%E8%A1%A8"><span class="nav-text">4. 向量表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E5%A4%8D%E4%BD%8D%E7%A8%8B%E5%BA%8F"><span class="nav-text">5. 复位程序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-%E4%B8%AD%E6%96%AD%E6%9C%8D%E5%8A%A1%E7%A8%8B%E5%BA%8F"><span class="nav-text">6. 中断服务程序</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-%E7%94%A8%E6%88%B7%E5%A0%86%E6%A0%88%E5%88%9D%E5%A7%8B%E5%8C%96"><span class="nav-text">7. 用户堆栈初始化</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%89%E3%80%81%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%88%9D%E5%A7%8B%E5%8C%96%E5%A0%86%E6%A0%88"><span class="nav-text">三、为什么要初始化堆栈</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/a7da6abe.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV16-11-STM32启动-01-STM32的启动文件 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV16-11-STM32启动-01-STM32的启动文件
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-06-04 22:06:47" itemprop="dateCreated datePublished" datetime="2023-06-04T22:06:47+08:00">2023-06-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">LV16-STM32开发</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>5.3k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>19 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是STM32开发——STM32启动文件的一些的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center">开发板</td>        <td align="left">正点原子 i.MX6ULL Linux阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">STM32开发板</td>        <td align="left">正点原子战舰V3(STM32F103ZET6)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <ul><li>通用</li></ul><table><tr><td align="center">分类  </td><td align="center">网址</td><td align="center">说明</td></tr><tr><td align="center" rowspan="4">官方网站</td><td align="left"><a href="https://www.arm.com/" target="_blank">https://www.arm.com/</a></td><td align="left">ARM官方网站，在这里我们可以找到Cotex-Mx以及ARMVx的一些文档</td></tr><tr>                                            <td align="left"><a href="https://www.st.com/content/st_com/zh.html" target="_blank">https://www.st.com/content/st_com/zh.html</a></td><td align="left">ST官方网站，在这里我们可以找到STM32的相关文档</td></tr><tr>                                            <td align="left"><a href="https://www.stmcu.com.cn/" target="_blank">https://www.stmcu.com.cn/</a></td><td align="left">意法半导体ST中文官方网站，在这里我们可以找到STM32的相关中文参考文档</td></tr><tr>                                            <td align="left"><a href="http://elm-chan.org/fsw/ff/00index_e.html" target="_blank">http://elm-chan.org/fsw/ff/00index_e.html</a></td><td align="left">FatFs文件系统官网</td></tr><tr><td align="center" rowspan="3">教程书籍</td><td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M3权威指南(中文).pdf" target="_blank">《ARM Cortex-M3权威指南》</a></td><td alirn="left" rowspan="3">ARM公司专家Joseph Yiu（姚文祥）的力作，中文翻译是NXP的宋岩</td></tr><tr>                                            <td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M0权威指南(中文).pdf" target="_blank">《ARM Cortex-M0权威指南》</a></td></tr><tr>                                            <td align="left"><a href="" target="_blank">《ARM Cortex-M3与Cortex-M4权威指南》</a></td></tr><tr><td align="center" rowspan="4">开发论坛</td><td align="left"><a href="http://47.111.11.73/forum.php" target="_blank">http://47.111.11.73/forum.php</a></td><td align="left">开源电子网，正点原子的资料下载及问题讨论论坛</td></tr><tr>                                            <td align="left"><a href="https://www.firebbs.cn/forum.php" target="_blank">https://www.firebbs.cn/forum.php</a></td><td align="left">国内Kinetis开发板-野火/秉火（刘火良）主持的论坛，现也做STM32和i.MX RT</td></tr><tr>                                            <td align="left"><a href="https://www.amobbs.com/index.php" target="_blank">https://www.amobbs.com/index.php</a></td><td align="left">阿莫（莫进明）主持的论坛，号称国内最早最火的电子论坛，以交流Atmel AVR系列单片机起家，现已拓展到嵌入式全平台，其STM32系列帖子有70W+。</td></tr><tr>                                            <td align="left"><a href="http://download.100ask.net/index.html" target="_blank">http://download.100ask.net/index.html</a></td><td align="left">韦东山嵌入式资料中心，有些STM32和linux的相关资料也可以来这里找。</td></tr><tr><td align="center" rowspan="3">博客参考</td><td align="left"><a href="http://www.openedv.com/" target="_blank">http://www.openedv.com/</a></td><td align="left">开源网-原子哥个人博客</td></tr><tr>                                            <td align="left"><a href="http://blog.chinaaet.com/jihceng0622" target="_blank">http://blog.chinaaet.com/jihceng0622</a></td><td align="left">博主是原Freescale现NXP的现场应用工程师</td></tr><tr>                                            <td align="left"><a href="https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/cortex-m-resources" target="_blank">cortex-m-resources</a></td><td align="left">这其实并不算是一个博客，这是ARM公司专家Joseph Yiu收集整理的所有对开发者有用的官方Cortex-M资料链接（也包含极少数外部资源链接）</td></tr></table><ul><li>STM32</li></ul><table>    <tr><td align="center" rowspan="2">STM32</td><td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103/hal_general/zh/latest/index.html" target="_blank">STM32 HAL库开发实战指南——基于F103系列开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr><tr>                                            <td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103badao/std/zh/latest/index.html" target="_blank">STM32库开发实战指南——基于野火霸道开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr></table><ul><li>SD卡</li></ul><table>    <tr><td align="left"><a href="https://www.sdcard.org/" target="_blank">SD Association</a></td><td align="left">提供了SD存储卡和SDIO卡系统规范</td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr><td align="left"><a href="https://www.st.com/resource/en/datasheet/stm32f103ze.pdf" target="_blank">STM32F103xx英文数据手册</a></td><td align="left">STM32F103xC/D/E系列的英文数据手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/709978" target="_blank">STM32F103xx中文数据手册</a></td><td align="left">STM32F103xC/D/E系列的中文数据手册</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/reference_manual/rm0008-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf" target="_blank">STM32F10xxx英文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的英文参考手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/710001" target="_blank">STM32F10xxx中文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的中文参考手册</td></tr>    <tr><td align="left"><a href="https://developer.arm.com/documentation/100165/0201/?lang=en" target="_blank">Arm Cortex-M3 处理器技术参考手册-英文版</a></td><td align="left">Cortex-M3技术参考手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/programming_manual/pm0056-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf" target="_blank">STM32F10xxx Cortex-M3编程手册-英文版(PM0056)</a></td><td align="left">STM32F10xxx/20xxx/21xxx/L1xxxx系列Cortex-M3编程手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/" target="_blank">SD卡相关资料——最新版本</a></td><td align="left">有关SD卡的一些资料可以从这里下载</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/archives/" target="_blank">SD卡相关资料——历史版本</a></td><td align="left">有关SD卡的一些历史版本资料可以从这里下载，比如后边看的SD卡2.0协议</td></tr>    <tr><td align="left"><a href="./" target="_blank">SD 2.0 协议标准完整版</a></td><td align="left">这是一篇关于SD卡2.0协议的中文文档，还是比较有参考价值的，可以一看</td></tr></table>
              </div>
            </details> 

<p>这一节我们来分析一下MDK工程中的STM32启动文件。</p>
<h1 id="一、启动文件"><a href="#一、启动文件" class="headerlink" title="一、启动文件"></a><font size=3>一、启动文件</font></h1><h2 id="1-启动文件简介"><a href="#1-启动文件简介" class="headerlink" title="1. 启动文件简介"></a><font size=3>1. 启动文件简介</font></h2><p>启动文件由汇编编写，是系统上电复位后第一个执行的程序。主要做了以下工作：  </p>
<p>（1）初始化堆栈指针 SP&#x3D;_initial_sp</p>
<p>（2）初始化 PC 指针 &#x3D;Reset_Handler</p>
<p>（3）初始化中断向量表</p>
<p>（4）配置系统时钟</p>
<p>（5）调用 C 库函数 __main 初始化用户堆栈，从而最终调用 main 函数去到 C 的世界 。</p>
<h2 id="2-启动文件在哪？"><a href="#2-启动文件在哪？" class="headerlink" title="2. 启动文件在哪？"></a><font size=3>2. 启动文件在哪？</font></h2><p>我是用的STM32CubeMX来生成的工程，启动文件就存在于 MDK-ARM&#x2F;startup_stm32f103xe.s ，它的内容后边再分析。</p>
<h2 id="3-查找ARM汇编指令资料"><a href="#3-查找ARM汇编指令资料" class="headerlink" title="3. 查找ARM汇编指令资料"></a><font size=3>3. 查找ARM汇编指令资料</font></h2><p>学习启动代码的时候，会涉及到 ARM 的汇编指令和 Cortex 内核的指令，有关 Cortex 内核的指令我们可以参考[《CM3 权威指南 》](STM32开发相关资料&#x2F;01ARM参考资料&#x2F;ARM Cortex-M3权威指南(中文).pdf)第四章：指令集。剩下的 ARM 的汇编指令我们可以在【MDK】&rarr;【Help】&rarr;【Uvision Help】 中搜索到 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530123816126.png" alt="image-20230530123816126" style="zoom:50%;" />

<p>检索出来的结果会有很多，我们只需要看 Assembler User Guide 这部分即可。下面列出了启动文件中使用到的 ARM 汇编指令，该列表的指令全部从 ARM Development Tools 这个帮助文档里面检索而来。其中编译器相关的指令 WEAK 和 ALIGN 为了方便也放在同一个表格了。  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530123929191.png" alt="image-20230530123929191" style="zoom:50%;" />

<h1 id="二、启动文件分析"><a href="#二、启动文件分析" class="headerlink" title="二、启动文件分析"></a><font size=3>二、启动文件分析</font></h1><h2 id="1-Stack——栈"><a href="#1-Stack——栈" class="headerlink" title="1. Stack——栈"></a><font size=3>1. Stack——栈</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Stack_Size	 EQU     0x400</span><br><span class="line">             AREA    STACK, NOINIT, READWRITE, ALIGN=3</span><br><span class="line">Stack_Mem    SPACE   Stack_Size</span><br><span class="line">__initial_sp</span><br></pre></td></tr></table></figure>

<p>（1）第1行：EQU，宏定义的伪指令，相当于等于，类似与C中的define。这里定义栈的大小为0x400，也就是1KB；</p>
<p>（2）第2行：AREA 是定义一个段，它将告诉汇编器汇编一个新的代码段或者数据段。此处定义的是栈段，没有初始化的段。STACK 表示段名，这个可以任意命名 ，NOINIT即不初始化，READWRITE表示可读可写，ALIGN是说段的起始地址应该是8的倍数，也就是8字节对齐；</p>
<p>（3）第3行：SPACE，用于分配一定大小的内存空间，单位为字节。这里指定大小等于Stack_Size，也就是开辟栈空间大小为0x400。</p>
<p>（4）第4行：__initial_sp是个标号，这个标号指向栈的栈顶，它紧挨着SPACE语句放置，表示栈的结束地址，即栈顶地址，栈是<strong>由高向低生长的</strong>。</p>
<p>栈的作用是用于局部变量，函数调用，函数形参等的开销，<strong>栈的大小不能超过内部SRAM的大小</strong>。如果编写的程序比较大， 定义的局部变量很多，那么就需要修改栈的大小。如果某一天，我们写的程序出现了莫名奇怪的错误，并进入了硬fault的时候，这时我们就要考虑下是不是栈不够大，溢出了。</p>
<h2 id="2-Heap——堆"><a href="#2-Heap——堆" class="headerlink" title="2. Heap——堆"></a><font size=3>2. Heap——堆</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Heap_Size      EQU     0x200								;定义堆的大小 512B</span><br><span class="line">                AREA    HEAP, NOINIT, READWRITE, ALIGN=3</span><br><span class="line">__heap_base													;堆的起始地址</span><br><span class="line">Heap_Mem        SPACE   Heap_Size							;堆的大小</span><br><span class="line">__heap_limit												;堆的结束地址</span><br></pre></td></tr></table></figure>

<p>（1）第1行：定义堆的大小为0x200，也就是512B；</p>
<p>（2）第2行：AREA 是定义一个段，此处定义的是堆段，没有初始化的堆，NOINIT即不初始化，READWRITE表示可读可写，align是8字节对齐；</p>
<p>（3）第3行：__heap_base，表示堆的起始地址。</p>
<p>（4）第4行：SPACE，用于分配一定大小的内存空间，单位为字节。这里指定大小等于Heap_Size，也就是开辟堆空间大小为0x200。</p>
<p>（5）第5行：__heap_limit是个标号，堆的结束地址。堆<strong>是由低向高生长的</strong>，跟栈的生长方向相反。</p>
<p>堆主要用来动态内存的分配，像malloc()函数申请的内存就在堆上面。这个在STM32里面用的比较少。</p>
<h2 id="3-堆栈对齐"><a href="#3-堆栈对齐" class="headerlink" title="3. 堆栈对齐"></a><font size=3>3. 堆栈对齐</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PRESERVE8</span><br><span class="line">THUMB</span><br></pre></td></tr></table></figure>

<p>（1）PRESERVE8：指定当前文件的堆栈按照8字节对齐。</p>
<p>（2）THUMB：表示后面指令兼容THUMB指令。THUBM是ARM以前的指令集，16bit，现在Cortex-M系列的都使用THUMB-2指令集， THUMB-2是32位的，兼容16位和32位的指令，是THUMB的超集。</p>
<h2 id="4-向量表"><a href="#4-向量表" class="headerlink" title="4. 向量表"></a><font size=3>4. 向量表</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">; Vector Table Mapped to Address 0 at Reset</span><br><span class="line">                AREA    RESET, DATA, READONLY</span><br><span class="line">                EXPORT  __Vectors</span><br><span class="line">                EXPORT  __Vectors_End</span><br><span class="line">                EXPORT  __Vectors_Size</span><br></pre></td></tr></table></figure>

<p>（1）第2行：定义一个数据段，名字为RESET，可读。  数据段放的是中断向量。</p>
<p>（2）第3~5行：EXPORT在程序中声明一个全局的标号，声明 __Vectors、__Vectors_End和__Vectors_Size这三个标号具有全局属性，<strong>可供外部的文件调用</strong>。如果是IAR编译器，则使用的是GLOBAL这个指令。</p>
<p>当内核响应了一个发生的异常后，对应的异常服务例程(ESR)就会执行。为了决定 ESR 的入口地址， 内核使用了“向量表查表机制”。 这里使用一张向量表。向量表其实是一个 WORD（ 32 位整数）数组，每个下标对应一种异常，该下标元素的值则是该 ESR的入口地址。 向量表在地址空间中的位置是可以设置的，通过 NVIC 中的一个重定位寄存器来指出向量表的地址。在复位后，该寄存器的值为 0。因此， 在地址 0 （即FLASH 地址0）处必须包含一张向量表，用于初始时的异常分配。要注意的是这里有个另类： 0 号类型并不是什么入口地址， 而是给出了复位后 MSP 的初值。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530124708848.png" alt="image-20230530124708848" style="zoom:50%;" />

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">__Vectors       DCD     __initial_sp               ; Top of Stack 存放__initial_sp，也就是堆栈栈顶的地址</span><br><span class="line">                DCD     Reset_Handler              ; Reset Handler</span><br><span class="line">                DCD     NMI_Handler                ; NMI Handler</span><br><span class="line">                DCD     HardFault_Handler          ; Hard Fault Handler</span><br><span class="line">                DCD     MemManage_Handler          ; MPU Fault Handler</span><br><span class="line">                DCD     BusFault_Handler           ; Bus Fault Handler</span><br><span class="line">                DCD     UsageFault_Handler         ; Usage Fault Handler</span><br><span class="line">                DCD     0                          ; Reserved</span><br><span class="line">                DCD     0                          ; Reserved</span><br><span class="line">                DCD     0                          ; Reserved</span><br><span class="line">                DCD     0                          ; Reserved</span><br><span class="line">                DCD     SVC_Handler                ; SVCall Handler</span><br><span class="line">                DCD     DebugMon_Handler           ; Debug Monitor Handler</span><br><span class="line">                DCD     0                          ; Reserved</span><br><span class="line">                DCD     PendSV_Handler             ; PendSV Handler</span><br><span class="line">                DCD     SysTick_Handler            ; SysTick Handler</span><br><span class="line"></span><br><span class="line">                ; External Interrupts</span><br><span class="line">                DCD     WWDG_IRQHandler            ; Window Watchdog</span><br><span class="line">                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect</span><br><span class="line">				; 中间的部分省略</span><br><span class="line">                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3</span><br><span class="line">                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 &amp; Channel5</span><br><span class="line">__Vectors_End</span><br><span class="line"></span><br><span class="line">__Vectors_Size  EQU  __Vectors_End - __Vectors</span><br></pre></td></tr></table></figure>

<p>（1）__Vectors为向量表起始地址，__Vectors_End 为向量表结束地址，两个相减即可算出向量表大小。</p>
<p>（2）向量表从FLASH的0地址开始放置，以4个字节为一个单位，地址0存放的是栈顶地址，0X04存放的是复位程序的地址，以此类推。 从代码上看，向量表中存放的都是中断服务函数的函数名，可我们知道C语言中的函数名就是一个地址。</p>
<p><strong>DCD</strong>：分配一个或者多个以字为单位的内存，要求四字节对齐，并要求初始化这些内存。在向量表中，DCD分配了一堆内存，并且以ESR的入口地址初始化它们。</p>
<h2 id="5-复位程序"><a href="#5-复位程序" class="headerlink" title="5. 复位程序"></a><font size=3>5. 复位程序</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">AREA    |.text|, CODE, READONLY		 ;text  一般代表代码段</span><br></pre></td></tr></table></figure>

<p>第1行：定义一个名称为 .text 的代码段，可读。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">; Reset handler routine</span><br><span class="line">Reset_Handler    PROC</span><br><span class="line">                 EXPORT  Reset_Handler                 [WEAK]     </span><br><span class="line">                 IMPORT  __main									 </span><br><span class="line">                 IMPORT  SystemInit  </span><br><span class="line">                 LDR     R0, =SystemInit			;复位子程序是系统上电后第一个执行的程序，调用 SystemInit 函数初始化系统时钟</span><br><span class="line">                 BLX     R0</span><br><span class="line">                 LDR     R0, =__main                ;__main 是一个标准的 C 库函数，主要作用是初始化用户堆栈，并在函数的最后调用main 函数去到 C 的世界</span><br><span class="line">                 BX      R0</span><br><span class="line">                 ENDP</span><br></pre></td></tr></table></figure>

<p>这个复位子程序是系统上电后第一个执行的程序，调用SystemInit函数初始化系统时钟，然后调用C库函数__mian，最终调用main函数去到C的世界。</p>
<p>（1）第3行：[WEAK]表示是一个弱符号声明，就是告诉编译器，我这里声明的标号的优先权低于其它同名的标号，也就是说如果在工程中还有别的函数和我同名，那么你就调用和我同名的其它函数，如果没有同名的，那你就调用我。</p>
<p>（2）第4行：IMPORT，表示该标号来自外部文件，跟C语言中的EXTERN关键字类似。这里表示SystemInit和__main这两个函数均来自外部的文件。SystemInit()是一个标准的库函数，在system_stm32f0xx.c这个库文件总定义。主要作用是配置系统时钟，这里调用这个函数之后，单片机的系统时钟配将会被配置。__main是一个标准的C库函数，主要作用是初始化用户堆栈，并在函数的最后调用main函数去到C的世界。这就是为什么我们写的程序都有一个main函数的原因。</p>
<p>LDR、 BLX、 BX 是 CM4 内核的指令，可在[《CM3 权威指南 》](STM32开发相关资料&#x2F;01ARM参考资料&#x2F;ARM Cortex-M3权威指南(中文).pdf)第四章-指令集里面查询到，具体作用见下表 ：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530125316861.png" alt="image-20230530125316861" style="zoom:50%;" />

<h2 id="6-中断服务程序"><a href="#6-中断服务程序" class="headerlink" title="6. 中断服务程序"></a><font size=3>6. 中断服务程序</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">; Dummy Exception Handlers (infinite loops which can be modified)</span><br><span class="line"></span><br><span class="line">NMI_Handler     PROC ; 系统异常</span><br><span class="line">                EXPORT  NMI_Handler                    [WEAK]  </span><br><span class="line">                B       .</span><br><span class="line">                ENDP</span><br><span class="line">; 中间部分省略</span><br><span class="line">SysTick_Handler PROC</span><br><span class="line">                EXPORT  SysTick_Handler                [WEAK]</span><br><span class="line">                B       .</span><br><span class="line">                ENDP</span><br><span class="line"></span><br><span class="line">Default_Handler PROC ;外部中断</span><br><span class="line">                EXPORT  WWDG_IRQHandler                [WEAK]</span><br><span class="line">                EXPORT  PVD_IRQHandler                 [WEAK]</span><br><span class="line">                EXPORT  RTC_IRQHandler                 [WEAK]</span><br><span class="line">				; 中间部分省略</span><br><span class="line"></span><br><span class="line">WWDG_IRQHandler</span><br><span class="line">PVD_IRQHandler</span><br><span class="line">RTC_IRQHandler</span><br><span class="line">;中间部分省略</span><br><span class="line"></span><br><span class="line">                B       .</span><br><span class="line"></span><br><span class="line">                ENDP</span><br></pre></td></tr></table></figure>

<p>在启动文件里面已经帮我们写好所有中断的中断服务函数，跟我们平时写的中断服务函数不一样的就是这些函数都是空的，真正的中断复服务程序需要我们在外部的 C 文件里面重新实现，这里只是提前占了一个位置而已。  </p>
<p>如果我们在使用某个外设的时候，开启了某个中断，但是又忘记编写配套的中断服务程序或者函数名写错，那当中断来临的时，程序就会跳转到启动文件预先写好的空的中断服务程序中，并且在这个空函数中无限循环，即程序就死在这里。  </p>
<p><strong>B</strong>：跳转到一个标号。这里跳转到一个‘ . ’，即表示无限循环。</p>
<h2 id="7-用户堆栈初始化"><a href="#7-用户堆栈初始化" class="headerlink" title="7. 用户堆栈初始化"></a><font size=3>7. 用户堆栈初始化</font></h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALIGN</span><br></pre></td></tr></table></figure>

<p>第1行：ALIGN，对指令或者数据存放的地址进行对齐，后面会跟一个立即数。缺省表示4字节对齐。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">;*******************************************************************************</span><br><span class="line">; User Stack and Heap initialization</span><br><span class="line">;*******************************************************************************</span><br><span class="line">                 IF      :DEF:__MICROLIB       ;检查是否定义了__MICROLIB,如果定义了则条件成立。用户可以在配置软件中勾选。</span><br><span class="line">				;用户栈和堆初始化,由C库函数_main来完成</span><br><span class="line">                 EXPORT  __initial_sp		  ;栈顶地址</span><br><span class="line">                 EXPORT  __heap_base		  ;堆起始地址</span><br><span class="line">                 EXPORT  __heap_limit         ;堆结束地址</span><br><span class="line"></span><br><span class="line">                 ELSE					</span><br><span class="line"></span><br><span class="line">                 IMPORT  __use_two_region_memory 	  </span><br><span class="line">                 EXPORT  __user_initial_stackheap   ;用户自己来初始化堆栈</span><br><span class="line"></span><br><span class="line">__user_initial_stackheap</span><br><span class="line"></span><br><span class="line">                 LDR     R0, =  Heap_Mem</span><br><span class="line">                 LDR     R1, = (Stack_Mem + Stack_Size)</span><br><span class="line">                 LDR     R2, = (Heap_Mem +  Heap_Size)</span><br><span class="line">                 LDR     R3, =  Stack_Mem</span><br><span class="line">                 BX      LR</span><br><span class="line"></span><br><span class="line">                 ALIGN</span><br><span class="line"></span><br><span class="line">                 ENDIF</span><br><span class="line"></span><br><span class="line">                 END</span><br></pre></td></tr></table></figure>

<p>第4行：首先判断是否定义了__MICROLIB ，如果定义了这个宏则赋予标号__initial_sp（栈顶地址）、 __heap_base（堆起始地址）、__heap_limit（堆结束地址）全局属性，可供外部文件调用。 有关这个宏我们在KEIL里面配置，具体见下图。然后堆栈的初始化就由C库函数__main来完成。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230409215812433.png" alt="image-20230409215812433" style="zoom:50%;" />

<p>如果没有定义__MICROLIB，则插入标号__use_two_region_memory，这个函数需要用户自己实现， 具体要实现成什么样，可在KEIL的帮助文档里面查询到：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530125809011.png" alt="image-20230530125809011" style="zoom:50%;" />

<p>（2）第15行：声明标号 __user_initial_stackheap 具有全局属性，可供外部文件调用，并实现这个标号的内容。  </p>
<p>（3）IF、ELSE、ENDIF：汇编的条件分支语句，跟 C 语言的 if ,else 类似，END：文件结束 。</p>
<h1 id="三、为什么要初始化堆栈"><a href="#三、为什么要初始化堆栈" class="headerlink" title="三、为什么要初始化堆栈"></a><font size=3>三、为什么要初始化堆栈</font></h1><p>这个嘛，我就按自己的理解先写这里，其实也不一定对，有错误的话欢迎指出，后边看到更权威的说明了，再补充。我们来看一下C语言程序的内存分布：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-11-STM32%E5%90%AF%E5%8A%A8-01-STM32%E7%9A%84%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6/img/image-20230530130729695.png" alt="image-20230530130729695" style="zoom:50%;" />

<ul>
<li>栈的作用是用于局部变量，函数调用，函数形参等的开销。</li>
<li>堆主要用来动态内存的分配。</li>
</ul>
<p>汇编中是不存在这些的，但是我们写的是C语言啊，即便最后也是被翻译成机器语言，也还是所以我们要想运行C语言程序的话，就需要有栈区和堆区，来存放不同的东西，C语言的运行离不开这两个区，所以我们需要在汇编中搭建好C语言的运行环境。</p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/a7da6abe.html">LV16-11-STM32启动-01-STM32的启动文件</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2023年06月04日 - 22:06</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/a7da6abe.html" title="LV16-11-STM32启动-01-STM32的启动文件">https://sumumm.github.io/post/a7da6abe.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV16-STM32%E5%BC%80%E5%8F%91/" rel="tag"><i class="fa fa-tag"></i> LV16-STM32开发</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/35d4a4a2.html" rel="prev" title="LV16-11-STM32启动-02-启动过程分析">
                  <i class="fa fa-angle-left"></i> LV16-11-STM32启动-02-启动过程分析
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/dd6fcfa9.html" rel="next" title="LV16-10-存储器系统-02-STM32">
                  LV16-10-存储器系统-02-STM32 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
